/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.mall.util.jsp.ImportTag
   Module Description   :

   Date Created      : 2010/1/7
   Original Author   : andy.chuang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.mall.util.jsp;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;



/**
 * @author andy.chuang
 *
 */
public class AroundTag extends BodyTagSupport {
    
    /**
     * 
     */
    private static final long serialVersionUID = 3682690788219329700L;
    private static Logger LOGGER=LoggerFactory.getLogger(AroundTag.class);
    private boolean enableCache=true;
//    private String cacheType="file";
//    private int timeout=-1;
    private String appendParameter;
    private String key;
    private String url;
    private String surfix;
    private BodyContent bodyContent;

    /**
     * @return the bodyContent
     */
    public BodyContent getBodyContent() {
        return bodyContent;
    }
    /**
     * @param bodyContent the bodyContent to set
     */
    public void setBodyContent(BodyContent bodyContent) {
        this.bodyContent = bodyContent;
    }
    /**
     * @return the url
     */
    public String getUrl() {
        return url;
    }
    /**
     * @param url the url to set
     */
    public void setUrl(String url) {
        this.url = url;
        String uri=null;
        if(url.indexOf("?")>0){
            uri=url.substring(0, url.indexOf("?"));
        }else{
            uri=url;
        }
        if(uri.indexOf(".")>0){
            surfix=uri.substring(uri.indexOf(".")+1, uri.length());
        }
    }
    /**
     * @return the enableCache
     */
    public boolean isEnableCache() {
        return enableCache;
    }
    /**
     * @param enableCache the enableCache to set
     */
    public void setEnableCache(boolean enableCache) {
        this.enableCache = enableCache;
    }

    /**
     * @return the appendParameter
     */
    public String getAppendParameter() {
        return appendParameter;
    }
    /**
     * @param appendParameter the appendParameter to set
     */
    public void setAppendParameter(String appendParameter) {
        this.appendParameter = appendParameter;
    }
    /**
     * @return the key
     */
    public String getKey() {
        return key;
    }
    /**
     * @param key the key to set
     */
    public void setKey(String key) {
        this.key = key;
    }
    private JspCacheManager jspCacheManager;
    public int doStartTag() throws JspException{
	WebApplicationContext wc=WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
	jspCacheManager=(JspCacheManager)wc.getBean("jspCacheManager");
	String resetCache=this.pageContext.getRequest().getParameter("resetCache");
	if(resetCache==null)resetCache="false";
	if(resetCache.equals("true")){
	    return EVAL_BODY_BUFFERED;
	}
	if(jspCacheManager==null){
	    LOGGER.error("jspCacheManager must to be set in spring context!!");
	}
	if(enableCache){
	    File file=jspCacheManager.getContent(key, url, appendParameter, pageContext.getRequest().getParameterMap());
	    if(file.exists()){
		return SKIP_BODY;
	    }
	} 
	return EVAL_BODY_BUFFERED;
    }
    public int doAfterBody() throws JspException{
	return EVAL_BODY_INCLUDE;
    }
    public int doEndTag() throws JspException{
	String resetCache=this.pageContext.getRequest().getParameter("resetCache");
	if(resetCache==null)resetCache="false";
	if(enableCache){
	    File file=jspCacheManager.getContent(key, url, appendParameter, pageContext.getRequest().getParameterMap());
	    if(!file.exists() || resetCache.equals("true")){
		String content=bodyContent.getString();
		InputStream is=new ByteArrayInputStream(content.getBytes());
		try {
		    writeContent(is);
		} catch (Exception e) {
		    LOGGER.error("eval body failed!!");
		    e.printStackTrace();
		}
		jspCacheManager.addCache(jspCacheManager.getKey(key, url, appendParameter, pageContext.getRequest().getParameterMap()), content);
	    }else{
		try {
		    InputStream is=new FileInputStream(file);
		    writeContent(is);
		} catch (Exception e) {
		   LOGGER.error("display static html failed!!html abs path:"+file.getAbsolutePath());
		}
	    }
	}else{
    	    String content=bodyContent.getString();
    	    InputStream is=new ByteArrayInputStream(content.getBytes());
	    try {
		writeContent(is);
	    } catch (Exception e) {
		LOGGER.error("display static html failed!!");
	    }
	}
	return EVAL_PAGE;
    }
    private void writeContent(InputStream is)throws Exception{
	Reader reader=new InputStreamReader(is, "UTF-8");
	    BufferedReader br=new BufferedReader(reader);
	        StringBuffer sb = new StringBuffer();
	        int i;

	        // under JIT, testing seems to show this simple loop is as fast
	        // as any of the alternatives
	        while ((i = br.read()) != -1)
	            sb.append((char)i);
	        is.close();
	        reader.close();
	        pageContext.getOut().print(sb.toString());
    }
   
    
}
